package view;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.swing.JComboBox;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.LineBorder;
import java.awt.Color;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.JOptionPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import operations.Relation;

import system.QuerySystem;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;

import javax.swing.JLabel;
import javax.swing.SwingConstants;

import exceptions.ExceptionFound;
import exceptions.ExceptionRelationLoad;

public class WindowQuerySystem {

	private JFrame frmQuerrysytem;
	private JTextField textField;
	private JTable table;
	private JComboBox<String> comboBox;
	private JPanel panelInput;
	private JLabel labelTotal;
	
	private QuerySystem system;
	
	private void backup(){
		try {
			system.backupRelations();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			JOptionPane.showMessageDialog(frmQuerrysytem, "Backup failure", "Backup", JOptionPane.ERROR_MESSAGE);
		}

		JOptionPane.showMessageDialog(frmQuerrysytem, "Backup up successfully", "Backup", JOptionPane.INFORMATION_MESSAGE);
	}
	
	private void query(){
		Relation result;
		int selected = comboBox.getSelectedIndex();
		
		switch (selected) {
		case 0:
			try {
				result = system.joinStudentsByCourse(textField.getText()).projection(2);
				loadTable(result, "Names");
				this.labelTotal.setText(String.valueOf(system.countInscritions(result)));
				result.close();

			} catch (ExceptionFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				JOptionPane.showMessageDialog(frmQuerrysytem, e.msgErro(), "Search " + e.getRelationName(), JOptionPane.ERROR_MESSAGE);
			}
			break;
		case 1:
			try {
				result = system.joinStudentsByDisciplnes(textField.getText()).projection(4);
				loadTable(result, "Names");
				this.labelTotal.setText(String.valueOf(system.countInscritions(result)));
				result.close();

			} catch (ExceptionFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				JOptionPane.showMessageDialog(frmQuerrysytem, e.msgErro(), "Search " + e.getRelationName(), JOptionPane.ERROR_MESSAGE);
			}
			break;
		case 2:
			try {
				result = system.joinInscritionsByCourse(textField.getText());
				loadTable(result, "Student ID", "Discipline ID", "Date inscritions", "Student matricule", "Student name", "Course ID", "Course Name");
				this.labelTotal.setText(String.valueOf(system.countInscritions(result)));
				result.close();

			} catch (ExceptionFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				JOptionPane.showMessageDialog(frmQuerrysytem, e.msgErro(), "Search " + e.getRelationName(), JOptionPane.ERROR_MESSAGE);
			}
			break;
		case 3:
			try {
				result = system.joinDisciplinesByStudent(textField.getText()).projection(1, 3, 4);
				loadTable(result, "Discipline ID", "Discipline name", "Credits");
				this.labelTotal.setText(String.valueOf(system.countInscritions(result)));
				result.close();

			} catch (ExceptionFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				JOptionPane.showMessageDialog(frmQuerrysytem, e.msgErro(), "Search " + e.getRelationName(), JOptionPane.ERROR_MESSAGE);
			}
			break;
		default:
			break;
		}
	}
	
	
	private void updateComboTitle(){
		int selected = comboBox.getSelectedIndex();
		
		switch (selected) {
		case 0:
			((TitledBorder)panelInput.getBorder()).setTitle("Entry with course name:");
			break;
		case 1:
			((TitledBorder)panelInput.getBorder()).setTitle("Entry with discipline name:");
			break;
		case 2:
			((TitledBorder)panelInput.getBorder()).setTitle("Entry with course name:");
			break;
		case 3:
			((TitledBorder)panelInput.getBorder()).setTitle("Entry with student name:");
			break;
		default:
			break;
		}
	}
		
	@SuppressWarnings("serial")
	private void loadTable(Relation relation, String... fields){
		
		String[] cellsTitles = new String[fields.length];
		String[][] cellsContent = new String[relation.size()][relation.getNumberOfFields()];
		
		//update table titles
		for (int i = 0; i < fields.length; i++) {
			cellsTitles[i] = fields[i];
		}
				
		//update table content
		for (int j = 0; j < relation.size(); j++) {
			for (int i = 0; i < relation.getNumberOfFields(); i++) {
				cellsContent[j][i] = relation.getRows().get(j).getFieldValue(i);
			}
		}

		
		((DefaultTableModel)table.getModel()).getDataVector().removeAllElements();
		((DefaultTableModel)table.getModel()).setRowCount(0);		
		
		table.setModel(new DefaultTableModel(cellsContent, cellsTitles){

			@SuppressWarnings("rawtypes")
			Class[] columnTypes = new Class[]{
				String.class
			};
			
			@SuppressWarnings({ "unchecked", "rawtypes" })
			public Class getColumnClass(int columnIndex) {
				return columnTypes[0];
			}
			
			boolean[] columnEditables = new boolean[] {
					false
				};
			public boolean isCellEditable(int row, int column) {
				return columnEditables[0];
			}

		});

		
		((DefaultTableModel)table.getModel()).setColumnCount(relation.getNumberOfFields());
		((DefaultTableModel)table.getModel()).setRowCount(relation.size());
		
		for (int i = 0; i < relation.getNumberOfFields(); i++) {
			table.getColumnModel().getColumn(i).setCellRenderer(new RenderCell());
		}
		table.repaint();

	}


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					WindowQuerySystem window = new WindowQuerySystem();
					window.frmQuerrysytem.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public WindowQuerySystem() {
		
		try {
			system = new QuerySystem();
		} catch (ExceptionRelationLoad e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			JOptionPane.showMessageDialog(frmQuerrysytem, e.msgErro(), "Load relations", JOptionPane.ERROR_MESSAGE);
			frmQuerrysytem.setVisible(false);
			System.exit(1);
		}
		
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void initialize() {
		frmQuerrysytem = new JFrame();
		frmQuerrysytem.setTitle("QuerySytem");
		frmQuerrysytem.setBounds(100, 100, 658, 521);
		frmQuerrysytem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "Type query", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		panelInput = new JPanel();
		panelInput.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "Entry course name:", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		textField = new JTextField();
		textField.setColumns(10);
		
		JButton btnQuery = new JButton("Query");
		btnQuery.setMnemonic('q');
		btnQuery.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				query();
			}
		});
		GroupLayout gl_panelInput = new GroupLayout(panelInput);
		gl_panelInput.setHorizontalGroup(
			gl_panelInput.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_panelInput.createSequentialGroup()
					.addContainerGap()
					.addComponent(textField, GroupLayout.DEFAULT_SIZE, 510, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addComponent(btnQuery)
					.addContainerGap())
		);
		gl_panelInput.setVerticalGroup(
			gl_panelInput.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelInput.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_panelInput.createParallelGroup(Alignment.BASELINE)
						.addComponent(textField, GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)
						.addComponent(btnQuery))
					.addContainerGap())
		);
		panelInput.setLayout(gl_panelInput);
		
		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new TitledBorder(null, "Result", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		labelTotal = new JLabel("0");
		labelTotal.setHorizontalAlignment(SwingConstants.RIGHT);
		
		JLabel label_1 = new JLabel("Total:");
		GroupLayout groupLayout = new GroupLayout(frmQuerrysytem.getContentPane());
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
						.addGroup(groupLayout.createSequentialGroup()
							.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
								.addComponent(panel_2, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE)
								.addComponent(panel, GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE)
								.addComponent(panelInput, GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE))
							.addGap(18))
						.addGroup(groupLayout.createSequentialGroup()
							.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 41, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(labelTotal, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
							.addGap(25))))
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(panel, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
					.addGap(12)
					.addComponent(panelInput, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
					.addGap(9)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(labelTotal)
						.addComponent(label_1))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(panel_2, GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE))
		);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		GroupLayout gl_panel_2 = new GroupLayout(panel_2);
		gl_panel_2.setHorizontalGroup(
			gl_panel_2.createParallelGroup(Alignment.TRAILING)
				.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 635, Short.MAX_VALUE)
		);
		gl_panel_2.setVerticalGroup(
			gl_panel_2.createParallelGroup(Alignment.LEADING)
				.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
		);
		
		table = new JTable();
		table.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
			}
		));
		//table.getColumnModel().getColumn(0).setPreferredWidth(530);
		scrollPane.setViewportView(table);
		panel_2.setLayout(gl_panel_2);
		
		comboBox = new JComboBox();
		comboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				updateComboTitle();
			}
		});
		comboBox.setModel(new DefaultComboBoxModel(new String[] {"List the names of all studends of course name", "List the names  of all students of disciplne name", "List number of inscritions of course name", "List all disciplines inscribes of student  name"}));
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addComponent(comboBox, GroupLayout.PREFERRED_SIZE, 598, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(25, Short.MAX_VALUE))
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addComponent(comboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(13, Short.MAX_VALUE))
		);
		panel.setLayout(gl_panel);
		frmQuerrysytem.getContentPane().setLayout(groupLayout);
		
		JMenuBar menuBar = new JMenuBar();
		frmQuerrysytem.setJMenuBar(menuBar);
		
		JMenu mnFile = new JMenu("File");
		mnFile.setMnemonic('F');
		menuBar.add(mnFile);
		
		JMenuItem mntmbackup = new JMenuItem("Backup");
		mntmbackup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				backup();
			}
		});
		mnFile.add(mntmbackup);
	}
}
